<template>
  <div class="chart-container">
    <vue-super-flow
      ref="flow"
      :origin="origin"
      :node-list="nodeList"
      :node-menu="nodeMenuList"
      :linkList="links"
      :link-menu="linkMenuList"
      :link-desc="linkDesc"
      :graph-menu="graphMenuList">
      <template v-slot:node="{meta}">
        <div class="slot-ellipsis">
          <i :class="meta.icon.header"></i> {{ meta.name }}
        </div>
        <div class="slot-body">
          <i :class="meta.icon.body"></i> {{ meta.desc }}
        </div>
      </template>
    </vue-super-flow>
    <el-dialog
      :title="drawerConf.title"
      :visible.sync="drawerConf.visible"
      :append-to-body="true"
      :close-on-click-modal="false"
      width="500px">

      <el-form
        @keyup.native.enter="settingSubmit"
        @submit.native.prevent
        v-show="drawerConf.type === drawerType.node"
        ref="nodeSetting"
        :model="nodeSetting">

        <el-form-item
          label="节点名称"
          prop="name">
          <el-input
            v-model="nodeSetting.name"
            placeholder="请输入节点名称"
            maxlength="30">
          </el-input>
        </el-form-item>

        <el-form-item
          label="节点描述"
          prop="desc">
          <el-input
            v-model="nodeSetting.desc"
            placeholder="请输入节点描述"
            maxlength="30">
          </el-input>
        </el-form-item>

        <!-- 额外属性 -->
        <el-form-item
          v-for="(parameter,index) in nodeSetting.parameters"
          :key="index"
          :label="parameter.label">
          <component
            :id="fdId"
            v-model="parameter.value"
            :is="parameter.component"
            :multiple="parameter.multiple"
            :type="parameter.type"
            :rows="parameter.rows"
            :value-format="parameter.valueFormat"
            :format="parameter.format"
            :placeholder="parameter.placeholder"
            style="width: 100%;" clearable>
            <el-option
              v-if="parameter.component === 'el-select'"
              v-for="option in $data[parameter.options]"
              :key="option.value"
              :label="option.label"
              :value="option.value">
            </el-option>
          </component>
        </el-form-item>
      </el-form>
      <el-form
        @keyup.native.enter="settingSubmit"
        @submit.native.prevent
        v-show="drawerConf.type === drawerType.link"
        ref="linkSetting"
        :model="linkSetting">
        <el-form-item
          label="连线描述"
          prop="desc">
          <el-input
            v-model="linkSetting.desc"
            placeholder="请输入连线描述">
          </el-input>
        </el-form-item>
        <el-form-item
          v-if="linkSetting.start && linkSetting.start.meta && linkSetting.start.meta.prop ==='condition'"
          label="连线条件"
          prop="condition">
          <el-input
            v-model="linkSetting.condition"
            placeholder="请输入连线条件">
          </el-input>
        </el-form-item>
      </el-form>
      <span
        slot="footer"
        class="dialog-footer">
        <el-button
          @click="drawerConf.cancel">
          取 消
        </el-button>
        <el-button
          type="primary"
          @click="settingSubmit">
          确 定
        </el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import VueSuperFlow from 'vue-super-flow'
import {save, getOne, getHandler} from "../../api";
import config from './config'
import {deepClone} from "../../utils";
import FormDialog from "./FormDialog";

const drawerType = {
  node: 0,
  link: 1
}

export default {
  components: {
    FormDialog,
    VueSuperFlow
  },
  data() {
    return {
      drawerType,
      fdId: '',
      drawerConf: {
        title: '',
        visible: false,
        type: null,
        info: null,
        open: (type, info) => {
          const conf = this.drawerConf
          conf.visible = true
          conf.type = type
          conf.info = info
          if (conf.type === drawerType.node) {
            conf.title = '节点'
            if (this.$refs.nodeSetting) this.$refs.nodeSetting.resetFields();
            this.$set(this.nodeSetting, 'name', info.meta['name']);
            this.$set(this.nodeSetting, 'desc', info.meta['desc']);
            this.$set(this.nodeSetting, 'parameters', info.meta['parameters']);
          } else {
            conf.title = '连线'
            if (this.$refs.linkSetting) this.$refs.linkSetting.resetFields()
            if (info && info.meta) {
              this.$set(this.linkSetting, 'name', info.meta['name']);
              this.$set(this.linkSetting, 'desc', info.meta['desc']);
              this.$set(this.linkSetting, 'condition', info.meta['condition']);
            }
            this.$set(this.linkSetting, 'start', info.start);
          }
        },
        cancel: () => {
          this.drawerConf.visible = false
          if (this.drawerConf.type === this.drawerType.node) {
            this.$refs.nodeSetting.clearValidate()
          } else {
            this.$refs.linkSetting.clearValidate()
          }
        }
      },
      linkSetting: {
        desc: '',
        name: '',
        start: '',
        condition: ''
      },
      nodeSetting: {
        name: '',
        desc: '',
        type: '',
        parameters: {}
      },
      origin: [0, 0],
      nodeList: [],
      nodeMenuList: [
        [
          {
            label: '删除',
            disable: false,
            hidden(node) {
              return node.meta.prop === 'start'
            },
            selected(node, coordinate) {
              node.remove()
            }
          }
        ],
        [
          {
            label: '编辑',
            selected: (node, coordinate) => {
              this.drawerConf.open(drawerType.node, node)
            }
          }
        ]
      ],
      links: [],
      linkMenuList: [
        [
          {
            label: '删除',
            disable: false,
            selected: (link, coordinate) => {
              link.remove()
            }
          }
        ],
        [
          {
            label: '编辑',
            disable: false,
            selected: (link, coordinate) => {
              this.drawerConf.open(drawerType.link, link)
            }
          }
        ]
      ],
      graphMenuList: [
        [
          {
            label: '开始节点',
            disable(graph) {
              return !!graph.nodeList.find(node => node.meta.prop === 'start')
            },
            selected: (graph, coordinate) => {
              const start = graph.nodeList.find(node => node.meta.prop === 'start')
              if (!start) {
                let node = config['start'];
                node.coordinate = coordinate;
                graph.addNode(deepClone(node));
              }
            }
          },
          {
            label: '条件节点',
            disable: false,
            selected: (graph, coordinate) => {
              let node = config['condition'];
              node.coordinate = coordinate;
              graph.addNode(deepClone(node));
            }
          },
          {
            label: '执行节点',
            disable: false,
            selected: (graph, coordinate) => {
              let node = config['approval'];
              node.coordinate = coordinate;
              graph.addNode(deepClone(node));
            }
          },
          {
            label: '定时节点',
            disable: false,
            selected: (graph, coordinate) => {
              let node = config['timer'];
              node.coordinate = coordinate;
              graph.addNode(deepClone(node));
            }
          },
          {
            label: 'HTTP节点',
            disable: false,
            selected: (graph, coordinate) => {
              let node = config['http'];
              node.coordinate = coordinate;
              graph.addNode(deepClone(node));
            }
          },
          {
            label: '结束节点',
            disable(graph) {
              return !!graph.nodeList.find(point => point.meta.prop === 'end')
            },
            selected: (graph, coordinate) => {
              let node = config['end'];
              node.coordinate = coordinate;
              graph.addNode(deepClone(node));
            }
          },
          {
            label: '保存数据',
            selected: (graph, coordinate) => {
              let data = {
                'fdId': this.fdId,
                'fdFlowyContext': JSON.stringify(graph)
              };
              save(data).then(res => {
                if (res && res.status === 200) {
                  if (res && res.data) {
                    this.$message({
                      message: '配置保存成功',
                      type: 'success'
                    });
                  }
                }
              });
            }
          },
          {
            label: '全选',
            selected: (graph, coordinate) => {
              graph.selectAll()
            }
          }
        ]
      ],
      listenerType: [],
    }
  },
  methods: {
    settingSubmit() {
      const conf = this.drawerConf
      if (this.drawerConf.type === drawerType.node) {
        if (!conf.info.meta) conf.info.meta = {}
        Object.keys(this.nodeSetting).forEach(key => {
          this.$set(conf.info.meta, key, this.nodeSetting[key])
        })
        this.$refs.nodeSetting.resetFields()
      } else {
        if (!conf.info.meta) conf.info.meta = {}
        Object.keys(this.linkSetting).forEach(key => {
          this.$set(conf.info.meta, key, this.linkSetting[key])
        })
        this.$refs.linkSetting.resetFields()
      }
      conf.visible = false
    },
    linkDesc(link) {
      return link.meta ? link.meta.desc : ''
    },
  },
  mounted() {
    if (this.$route.query && this.$route.query.fdId) {
      this.fdId = this.$route.query.fdId;
      getOne(this.fdId).then(res => {
        if (res && res.status === 200) {
          let context = JSON.parse(res.data.data.fdFlowyContext);
          if (context) {
            this.nodeList = context.nodeList;
            this.links = context.linkList;
          }
        }
      });
    }
    getHandler().then(res => {
      if (res && res.status === 200) {
        this.listenerType = res.data;
      }
    });
  }
}
</script>
<style scoped>
.node {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 50px;
  margin-top: 20px;
  margin-bottom: 20px;
  border-radius: 10px;
  border: 2px solid rgb(187, 187, 187);
}

.chart-container {
  width: 100%;
  height: 100%;
  background-image: linear-gradient(transparent, transparent 10px, #CCC 10px, #CCC 11px),
  linear-gradient(-90deg, transparent, transparent 10px, #CCC 10px, #CCC 11px);
  background-size: 11px 11px;
  background-position: 0 0, 0 0;
}

.slot-ellipsis {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 30px;
  background-color: #CCCCCC;
}

.slot-body {
  margin-top: 10px;
}

/deep/ .super-flow__menu {
  width: 100px;
}

/deep/ .super-flow__menu-item-content {
  width: 90px;
}

/deep/ .super-flow__menu-item-icon {
  width: 0px;
  height: 0px;
}

</style>
